<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        
        <title>Level editor</title>
        
        <!-- Our CSS stylesheet file -->
        <link rel="stylesheet" href="assets/css/styles.css" />
        
        <!--[if lt IE 9]>
          <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
        <![endif]-->
		<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
		<script>
			$(document).ready(function(){
				$(".redactor").hide();
			
				var cells = [];
				var items = [];
				var currentW = 0;
				var cellsN;
				var cellsM;
				
				var player = new Entity(5,5,0);
				var exit = new Entity(0,0,0);
				var enemies = [];
				
				$("#create").click(function() {
					cellsN = $("#n").val();
					cellsM = $("#m").val();
					
					fillTableWithEmptyCells(cellsN, cellsM);
					$(".initElement").hide();
					$(".redactor").show();
				});
				
				var currentBlock = 'wall';//also can be 'enemy' and 'player'
				
				$('#buildingBlockSelector input').click(function() {
					currentBlock = $(this).val();
				});
				
				//Entity object with i, j and w
				function Entity (i, j, w) {
					this.i = i;
					this.j = j;
					this.w = w;
				}
				
				//Item object with i, j and w (same as Entity) plus item type
				function Item (i, j, w, t) {
					this.i = i;
					this.j = j;
					this.w = w;
					this.t = t;
				}
				
				function fillTableWithEmptyCells(n, m) {
					var tableCode = '';
					for(var i = 0; i < n; i++) {
						tableCode += '<tr>';
						
						for(var j = 0; j < m; j++) {
							tableCode += '<td rownr="' + i + '" colnr="' + j + '"></td>';
						}
						
						tableCode += '</tr>';
					}
					$('#levelTable').html(tableCode);
					
					generateTextField();
					drawTableForCurrentW();
				}
				
				function drawTableForCurrentW() {
					var currW = parseInt(0);
					//mark everything with white
					$("td").each(function(index) {
						$(this).removeClass("taken taken_ana taken_kata has_enemy has_player has_exit has_medkit has_energy has_rocket");
					});
				
					//give cells on screen all the classes that represent their state
					cells.forEach(function(cell) {
						var $correspondingCell = $("td[rownr='" + cell.i + "'][colnr='" + cell.j + "']");
						
						if(cell.w == currW + 1) {
							$correspondingCell.addClass("taken_ana");
						}
						if(cell.w == currW - 1) {
							$correspondingCell.addClass("taken_kata");
						}
						if(cell.w == currW) {
							$correspondingCell.addClass("taken");
						}
					});
					
					for(var i = 0; i < cellsN; i++) {
						for(var j = 0; j < cellsM; j++) {
							var $cellOnScreen = $("td[rownr='" + i + "'][colnr='" + j + "']");
							
							//only black walls remain
							if($cellOnScreen.hasClass("taken")) {
								$cellOnScreen.removeClass("taken_ana");
								$cellOnScreen.removeClass("taken_kata");
							}
							
							//draw enemies
							enemies.forEach(function(enemy) {
								if(enemy.w == 0  &&  i == enemy.i  &&  j == enemy.j) {
									$cellOnScreen.addClass("has_enemy");
								}
							});
							
							//draw items
							items.forEach(function(item) {
								if(item.w == 0  &&  i == item.i  &&  j == item.j) {
									if(item.t == 'q') {
										$cellOnScreen.addClass("has_exit");
									}
									if(item.t == 'e') {
										$cellOnScreen.addClass("has_energy");
									}
									if(item.t == 'm') {
										$cellOnScreen.addClass("has_medkit");
									}
									if(item.t == 'r') {
										$cellOnScreen.addClass("has_rocket");
									}
								}
							});
							
							//draw player
							if(player.w == 0  &&  i == player.i  &&  j == player.j) {
								$cellOnScreen.addClass("has_player");
							}
							
							//draw exit
							if(exit.w == 0  &&  i == exit.i  &&  j == exit.j) {
								$cellOnScreen.addClass("has_exit");
							}
						}
					}					
				}
				
				$("#levelTable").on('click', 'td', function() {
					var thisRow = $(this).attr("rownr");
					var thisCol = $(this).attr("colnr");
					
					if(currentBlock == 'wall') {
						if($(this).hasClass("has_player") || $(this).hasClass("has_enemy") || $(this).hasClass("has_exit") || $(this).hasClass("has_medkit") || $(this).hasClass("has_energy") || $(this).hasClass("has_rocket")) {
							return;
						}
						
						//check for existance and delete if exists
						var wasDeleted = false;
						
						cells.forEach(function(cell) {
							if(cell.w == 0  &&  thisRow == cell.i  &&  thisCol == cell.j) {
								var ind = cells.indexOf(cell);
								if (ind > -1) {
									cells.splice(ind, 1);
								}
								wasDeleted = true;
							}
						});
						//not exist - add
						if(wasDeleted == false) {
							cells.push(new Entity(thisRow, thisCol, 0));
						}
					}
					
					if(currentBlock == 'enemy') {
						if($(this).hasClass("has_player") || $(this).hasClass("taken") || $(this).hasClass("has_exit") || $(this).hasClass("has_medkit") || $(this).hasClass("has_energy") || $(this).hasClass("has_rocket")) {
							return;
						}
						
						//check for existance and delete if exists
						var wasDeleted = false;
						
						enemies.forEach(function(enemy) {
							if(enemy.w == 0  &&  thisRow == enemy.i  &&  thisCol == enemy.j) {
								var ind = enemies.indexOf(enemy);
								if (ind > -1) {
									enemies.splice(ind, 1);
								}
								wasDeleted = true;
							}
						});
						//not exist - add
						if(wasDeleted == false) {
							enemies.push(new Entity(thisRow, thisCol, 0));
						}
					}
					
					if(currentBlock == 'medkit') {
						if($(this).hasClass("has_player") || $(this).hasClass("has_enemy") || $(this).hasClass("has_exit") || $(this).hasClass("taken") || $(this).hasClass("has_energy") || $(this).hasClass("has_rocket")) {
							return;
						}
						
						//check for existance and delete if exists
						var wasDeleted = false;
						
						items.forEach(function(item) {
							if(item.w == 0  &&  thisRow == item.i  &&  thisCol == item.j) {
								var ind = items.indexOf(item);
								if (ind > -1) {
									items.splice(ind, 1);
								}
								wasDeleted = true;
							}
						});
						//not exist - add
						if(wasDeleted == false) {
							items.push(new Item(thisRow, thisCol, 0, 'm'));
						}
					}
					
					if(currentBlock == 'energy') {
						if($(this).hasClass("has_player") || $(this).hasClass("has_enemy") || $(this).hasClass("has_exit") || $(this).hasClass("has_medkit") || $(this).hasClass("taken") || $(this).hasClass("has_rocket")) {
							return;
						}
						
						//check for existance and delete if exists
						var wasDeleted = false;
						
						items.forEach(function(item) {
							if(item.w == 0  &&  thisRow == item.i  &&  thisCol == item.j) {
								var ind = items.indexOf(item);
								if (ind > -1) {
									items.splice(ind, 1);
								}
								wasDeleted = true;
							}
						});
						//not exist - add
						if(wasDeleted == false) {
							items.push(new Item(thisRow, thisCol, 0, 'e'));
						}
					}
					
					if(currentBlock == 'rocket') {
						if($(this).hasClass("has_player") || $(this).hasClass("has_enemy") || $(this).hasClass("has_exit") || $(this).hasClass("has_medkit") || $(this).hasClass("taken") || $(this).hasClass("has_energy")) {
							return;
						}
						
						//check for existance and delete if exists
						var wasDeleted = false;
						
						items.forEach(function(item) {
							if(item.w == 0  &&  thisRow == item.i  &&  thisCol == item.j) {
								var ind = items.indexOf(item);
								if (ind > -1) {
									items.splice(ind, 1);
								}
								wasDeleted = true;
							}
						});
						//not exist - add
						if(wasDeleted == false) {
							items.push(new Item(thisRow, thisCol, 0, 'r'));
						}
					}
					
					if(currentBlock == 'player') {
						if($(this).hasClass("has_enemy") || $(this).hasClass("taken") || $(this).hasClass("has_exit") || $(this).hasClass("has_medkit") || $(this).hasClass("has_energy") || $(this).hasClass("has_rocket")) {
							return;
						}
					
						player = new Entity(thisRow, thisCol, 0);
					}
					
					if(currentBlock == 'exit') {
						if($(this).hasClass("has_enemy") || $(this).hasClass("taken") || $(this).hasClass("has_player") || $(this).hasClass("has_medkit") || $(this).hasClass("has_energy") || $(this).hasClass("has_rocket")) {
							return;
						}
					
						exit = new Entity(thisRow, thisCol, 0);
					}
					
					generateTextField();
					drawTableForCurrentW();
				});
				
				
				function CellLine (coords2d, singleW) {
					this.coords2d = coords2d;
					this.singleW = singleW;
				}
				
				function CellObject (coords2d) {
					this.coords2d = coords2d;
					this.wCoords = [];
					
					function addW(w) {
						this.wCoords.push(w);
					}
				}
				
				function generateTextField() {
					//define level size
					var levelAsText = cellsN + ',' + cellsM + '\n';
					
					//set player's position
					levelAsText += player.i + ',' + player.j + ',' + player.w + '\n';
					
					//set enemies positions
					enemies.forEach(function(enemy) {
						levelAsText += enemy.i + ',' + enemy.j + ',' + enemy.w + ';';
					});
					levelAsText += '\n';
					
					//set items positions
					levelAsText += 'q,' + exit.i + ',' + exit.j + ',' + exit.w + ';';
					items.forEach(function(item) {
						levelAsText += item.t + ',' + item.i + ',' + item.j + ',' + item.w + ';';
					});
					levelAsText += '\n';
					
					//generate raw lines
					var cellLines = [];
					cells.forEach(function(cell) {						
						cellLines.push(new CellLine(cell.i + ',' + cell.j, cell.w));
					});
					
					//generate non-unique cell objects
					var cellObjects = [];
					cellLines.forEach(function(cellLine) {						
						cellObjects.push(new CellObject(cellLine.coords2d));
					});
					
					//remove duplicates from cell objects array
					var uniqueCells = [];
					$.each(cellObjects, function(i, cell){
						if($.inArray(cell, uniqueCells) === -1) uniqueCells.push(cell);
					});
					
					//fill array of unique 2d coordinate cells with their w values
					uniqueCells.forEach(function(uniqueCell) {						
						cellLines.forEach(function(line) {						
							if(line.coords2d === uniqueCell.coords2d) {
								uniqueCell.wCoords.push(line.singleW);
							}
						});
					});
					
					//output lines
					var lines = [];
					uniqueCells.forEach(function(cell) {	
						lines.push(cell.coords2d + '=' + cell.wCoords);
					});
					
					//remove duplicates from output lines
					var resultLines = [];
					$.each(lines, function(i, line){
						if($.inArray(line, resultLines) === -1) resultLines.push(line);
					});
					
					//generate output text
					resultLines.forEach(function(resLine) {	
						levelAsText += resLine + '\n';
					});
					
					$('#resultingText').html(levelAsText);
				}
			});
		</script>
    </head>
    
    <body>
	
		<!--initial elements-->
		
        <header><h1>Level-redactor</h1></header>
		<h4 class="initElement">Level length and height:</h4>
		
		<br class="initElement">
		
		<select class="initElement" id="n">
			<option value="10">10</option>
			<option value="15">15</option>
			<option value="20">20</option>
			<option value="25">25</option>
		</select>
		<span class="initElement">x</span>
		<select class="initElement" id="m">
			<option value="10">10</option>
			<option value="15">15</option>
			<option value="20">20</option>
			<option value="25">25</option>
		</select>
		
		<a class="blueButton initElement" id="create" class="initElement">
			Create!
		</a>
		
		
		
		
		
		
		<!--redactor itself-->
		
		<table id="markupTable" class="redactor">
			<tr>
				<td>
					<table id="levelTable">
						<!--Content is drawn here dynamically-->
					</table>
				</td>
				<td id="buildingBlockSelector">
					<form action="">
						<input type="radio" name="level_block" value="wall" checked>Wall<br>
						<input type="radio" name="level_block" value="enemy">Enemy<br>
						<input type="radio" name="level_block" value="player">Player<br>

						<input type="radio" name="level_block" value="exit">Exit<br>
						<input type="radio" name="level_block" value="medkit">Medkit<br>
						<input type="radio" name="level_block" value="energy">Energy<br>
						<input type="radio" name="level_block" value="rocket">Rocket<br>
					</form>
				</td>
			</tr>
		</table>
		


		
		
		
		
		
		<br>
        <form action="./" method="post" class="redactor">
			Level name: <input id="level_name" type="text" name="FirstName" value="">
			<a href="#" class="blueButton" id="download">Save level</a>
			<br><br>
            <textarea id="resultingText" hidden></textarea>
        </form>

		<!-- Footer below -->
        <footer>
			<b> This redactor PHP, HTML, CSS and JS code is based on <a href="http://tutorialzine.com/2011/05/generating-files-javascript-php/">text-file generation tutorial on Tutorialzine.com</a></b>
		</footer>
		
        <!--script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script-->
        <script src="assets/js/jquery.generateFile.js"></script>
        <script src="assets/js/script.js"></script> 
    </body>
</html>
